package com.university.mentalhealthplatform.global.rbac.service.entity;

import com.university.mentalhealthplatform.global.rbac.dto.normal.RoleDTO;
import com.university.mentalhealthplatform.exception.RoleNotFoundException;
import com.university.mentalhealthplatform.global.rbac.model.Menu;
import com.university.mentalhealthplatform.global.rbac.model.Permission;
import com.university.mentalhealthplatform.global.rbac.model.Role;
import com.university.mentalhealthplatform.global.rbac.repository.MenuRepository;
import com.university.mentalhealthplatform.global.rbac.repository.PermissionRepository;
import com.university.mentalhealthplatform.global.rbac.repository.RoleRepository;
import com.university.mentalhealthplatform.global.rbac.service.relation.RoleMenuService;
import com.university.mentalhealthplatform.global.rbac.service.relation.RolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.*;
import java.util.stream.Collectors;

@Service
public class RoleService {

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PermissionRepository permissionRepository;

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private RoleMenuService roleMenuService;


    // 获取所有角色，并将其转换为 RoleDTO 列表
    public List<RoleDTO> getAllRoles() {
        // 查询数据库中的所有角色
        List<Role> roles = roleRepository.findAll();

        // 将 Role 对象转换为 RoleDTO 对象，并返回列表
        return roles.stream()
                .map(RoleDTO::new)  // 使用 RoleDTO 构造函数将 Role 转换为 RoleDTO
                .collect(Collectors.toList());
    }


    public Optional<Role> getRoleById(Long id) {
        return roleRepository.findById(id);
    }

    public Role createRoleIfNotFound(String roleName,String displayName, Set<Permission> permissions) {
        // 尝试查找是否已存在对应的角色
        Optional<Role> existingRole = roleRepository.findByIdentifier(roleName);

        // 如果角色已存在，直接返回
        if (existingRole.isPresent()) {
            return existingRole.get();
        }

        // 如果角色不存在，创建并保存新的角色
        Role role = new Role();
        role.setIdentifier(roleName);
        role.setPermissions(permissions);
        role.setDisplayName(displayName);

        return roleRepository.save(role);
    }





    public Role updateRole(Long id, String roleName, Set<Permission> permissions) {
        Role role = roleRepository.findById(id).orElseThrow(() -> new RuntimeException("Role not found"));
        role.setIdentifier(roleName);
        role.setPermissions(permissions);
        return roleRepository.save(role);
    }

    public void deleteRole(Long id) {
        Role role = roleRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Role with ID " + id + " not found"));

        roleRepository.deleteById(id);
    }


    public void toggleRoleStatus(Long id) {
        Role role = roleRepository.findById(id).orElseThrow(() -> new RuntimeException("Role not found"));
        role.toggleStatus();
        roleRepository.save(role);
    }

    ////////////////////////////////////////////////
    //////
    ////// 控制器调用方法
    //////
    ////////////////////////////////////////////////

    public Role createRole(RoleDTO roleDTO){
        // 尝试查找是否已存在对应的角色
        Optional<Role> existingRole = roleRepository.findByIdentifier(roleDTO.getIdentifier());

        if (existingRole.isPresent()) {
            // 如果角色已存在，抛出异常或返回错误信息
            throw new IllegalArgumentException("角色已存在: " + roleDTO.getIdentifier());
        }

        // 如果角色不存在，创建并保存新的角色
        Role role = new Role();
        role.setIdentifier(roleDTO.getIdentifier());
        role.setDisplayName(roleDTO.getDisplayName());
        role.setOrderNum(roleDTO.getOrderNum());
        role.setStatus(roleDTO.isStatus());

        return roleRepository.save(role);

    }

    // 更新角色基本信息
    public Role updateRole(Long roleId, RoleDTO roleDTO) {
        // 查找角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色未找到: " + roleId));

        // 更新角色的基本信息
        role.setDisplayName(roleDTO.getDisplayName());
        role.setIdentifier(roleDTO.getIdentifier());
        role.setOrderNum(roleDTO.getOrderNum());
        role.setStatus(roleDTO.isStatus());

        // 保存更新后的角色
        return roleRepository.save(role);
    }



    public void assignMenusToRole(Long roleId, List<Long> menuIds) {
        // 查找角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色未找到: " + roleId));

        // 从数据库中找到所有的菜单 ID
        List<Menu> newMenus = menuRepository.findAllById(menuIds);

        // 获取角色当前已有的菜单
        Set<Menu> existingMenus = role.getMenus();

        // 将新的菜单追加到现有的菜单集合中
        existingMenus.addAll(newMenus);

        // 保存角色与菜单的关系
        roleRepository.save(role);
    }




    public void assignPermissionsToRole(Long roleId, List<Long> permissionIds) {
        // 查找角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色未找到: " + roleId));

        // 从数据库中找到所有的权限 ID
        List<Permission> newPermissions = permissionRepository.findAllById(permissionIds);

        // 获取角色当前已有的权限
        Set<Permission> existingPermissions = role.getPermissions();

        // 将新的权限追加到现有的权限集合中
        existingPermissions.addAll(newPermissions);

        // 保存角色与权限的关系
        roleRepository.save(role);
    }

    public void removeMenusFromRole(Long roleId, List<Long> menuIds) {
        // 查找角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色未找到: " + roleId));

        // 从数据库中找到需要撤回的菜单
        List<Menu> menusToRemove = menuRepository.findAllById(menuIds);

        // 获取角色当前已有的菜单
        Set<Menu> existingMenus = role.getMenus();

        // 从现有菜单集合中移除指定的菜单
        existingMenus.removeAll(menusToRemove);

        // 保存角色与菜单的关系
        roleRepository.save(role);
    }


    public void removePermissionsFromRole(Long roleId, List<Long> permissionIds) {
        // 查找角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色未找到: " + roleId));

        // 从数据库中找到需要撤回的权限
        List<Permission> permissionsToRemove = permissionRepository.findAllById(permissionIds);

        // 获取角色当前已有的权限
        Set<Permission> existingPermissions = role.getPermissions();

        // 从现有权限集合中移除指定的权限
        existingPermissions.removeAll(permissionsToRemove);

        // 保存角色与权限的关系
        roleRepository.save(role);
    }


    // 获取角色的菜单 ID 列表
    public List<Long> getMenuIdsByRoleId(Long roleId) {
        return roleRepository.findById(roleId)
                .map(role -> role.getMenus().stream().map(Menu::getId).collect(Collectors.toList()))
                .orElseThrow(() -> new RuntimeException("角色未找到"));
    }

    // 获取角色的权限 ID 列表
    public List<Long> getPermissionIdsByRoleId(Long roleId) {
        return roleRepository.findById(roleId)
                .map(role -> role.getPermissions().stream().map(Permission::getId).collect(Collectors.toList()))
                .orElseThrow(() -> new RuntimeException("角色未找到"));
    }

    public void deleteRoleById(Long roleId) {
        if (!roleRepository.existsById(roleId)) {
            throw new RoleNotFoundException("角色不存在");
        }
        roleRepository.deleteById(roleId); // 删除角色
    }



    public void updateRoleStatus(Long roleId, boolean newStatus) {
        // 查找角色
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色未找到: " + roleId));

        role.setStatus(newStatus);

        roleRepository.save(role);
    }
}
